home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / utils.c < prev   
Encoding:
C/C++ Source or Header  |  1992-09-01  |  14.5 KB  |  725 lines

  1. /* 
  2.  * utils.c--
  3.  *
  4.  *    Simple utility functions for Jaquith archive package.
  5.  *
  6.  * Copyright 1992 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "The question of whether a computer can think is no more
  17.  *      interesting than the question of whether a submarine can swim."
  18.  *      -- Dijkstra
  19.  *
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/utils.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  24. #endif /* not lint */
  25.  
  26. #include "jaquith.h"
  27.  
  28. #if (defined(SYSV) && !defined(dynix))
  29. extern char *getcwd();
  30. #else
  31. extern char *getwd();
  32. #endif
  33.  
  34. /* file globals */
  35. static char printBuf[T_MAXSTRINGLEN];
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * Utils_Bailout--
  41.  *
  42.  *    print message in desired fashion and abort.
  43.  *
  44.  * Results:
  45.  *    none.
  46.  *
  47.  * Side effects:
  48.  *    Kill's program.
  49.  *
  50.  *----------------------------------------------------------------------
  51.  */
  52.  
  53. void
  54. Utils_Bailout(msg, disposition)
  55.     char *msg;                /* Death message */
  56.     int disposition;          /* Indicator of message type */
  57. {
  58.  
  59.     switch (disposition) {
  60.     case BAIL_PRINT:
  61.         fprintf(stderr,"%s\n", msg);
  62.     break;
  63.     case BAIL_PERROR:
  64.         perror(msg);
  65.     break;
  66.     case BAIL_HERROR:
  67. #ifdef sunos
  68.         perror(msg);
  69. #else
  70.     herror(msg);
  71. #endif
  72.     break;
  73.     default:
  74.     fprintf(stderr,"!!Unexpected msg type (%d) in Bailout. msg was:\n",
  75.         disposition);
  76.         fprintf(stderr,"%s\n", msg);
  77.     break;
  78.     }
  79.     exit(T_FAILURE);
  80.  
  81. }
  82.  
  83.  
  84. /*
  85.  *----------------------------------------------------------------------
  86.  *
  87.  * Utils_GetWorkingDir --
  88.  *
  89.  *    Figure out where the hell we are
  90.  *
  91.  * Results:
  92.  *    Returns a ptr to current working directory and its length
  93.  *
  94.  * Side effects:
  95.  *    None.
  96.  *
  97.  *----------------------------------------------------------------------
  98.  */
  99.  
  100. void
  101. Utils_GetWorkingDir(path, pathLenPtr)
  102.     char *path;               /* receiving path */
  103.     int *pathLenPtr;          /* ptr to receiving length */
  104. {
  105.     if (GETWD(path, pathLenPtr) == NULL) {
  106.     *path = '\0';
  107.     *pathLenPtr = 0;
  108.     } else {
  109.     *pathLenPtr = strlen(path);
  110.     }
  111.  
  112. }
  113.  
  114.  
  115. /*
  116.  *----------------------------------------------------------------------
  117.  *
  118.  * Utils_MakeFullPath
  119.  *
  120.  *    Expand simple filename to absolute pathname
  121.  *
  122.  * Results:
  123.  *    Returns a ptr to the full pathname.
  124.  *
  125.  * Side effects:
  126.  *    None.
  127.  *
  128.  *----------------------------------------------------------------------
  129.  */
  130.  
  131. char *
  132. Utils_MakeFullPath(relPath)
  133.     char *relPath;               /* simple file name (we think) */
  134. {
  135.     char root[T_MAXPATHLEN];
  136.     int len = sizeof(root);
  137.  
  138.     if (*relPath == '/') {
  139.     return Str_Dup(relPath);
  140.     }
  141.  
  142.     Utils_GetWorkingDir(root, &len);
  143.  
  144.     if (*relPath) {
  145.     return Str_Cat(3, root, "/", relPath);
  146.     } else {
  147.     return Str_Dup(root);
  148.     }
  149.  
  150. }
  151.  
  152.  
  153. /*
  154.  *----------------------------------------------------------------------
  155.  *
  156.  * Utils_CheckName --
  157.  *
  158.  *    Validate a filename
  159.  *
  160.  * Results:
  161.  *    T_SUCCESS or T_FAILURE
  162.  *
  163.  * Side effects:
  164.  *    none.
  165.  *
  166.  *----------------------------------------------------------------------
  167.  */
  168.  
  169. int
  170. Utils_CheckName(name, noWhiteSpace)
  171.     char *name;               /* filename to validate */
  172.     int noWhiteSpace;         /* 1== whitespace not allowed */
  173. {
  174.     if ((name == NULL) || (!*name)) {
  175.     return T_FAILURE;
  176.     }
  177.  
  178.     while (*name) {
  179.     if ((isspace(*name) && noWhiteSpace) ||
  180.         (!(isprint(*name)))) {
  181.         return (T_FAILURE);
  182.     }
  183.     name++;
  184.     }
  185.  
  186.     return(T_SUCCESS);
  187.     
  188. }
  189.  
  190.  
  191. /*
  192.  *----------------------------------------------------------------------
  193.  *
  194.  * Utils_ReadLine --
  195.  *
  196.  *    Get a line from config file
  197.  *
  198.  * Results:
  199.  *    Ptr to buffer.
  200.  *
  201.  * Side effects:
  202.  *    None.
  203.  *
  204.  *----------------------------------------------------------------------
  205.  */
  206.  
  207. char *
  208. Utils_ReadLine(stream, stripFlag)
  209.     FILE *stream;             /* input stream from fopen */
  210.     int stripFlag;            /* remove trailing '\n' */
  211. {
  212.     int len;
  213.     static char buf[T_MAXLINELEN];
  214.  
  215.     while (fgets(buf, sizeof(buf), stream) != NULL) {
  216.     if ((*buf == COMMENT_CHAR) || (*buf == '\n')) {
  217.         continue;
  218.     }
  219.     len = strlen(buf)-1;
  220.     if (buf[len] != '\n') {
  221.         Utils_Bailout("ReadLine: Line too long.\n", BAIL_PRINT);
  222.     }
  223.     if (stripFlag) {
  224.         buf[len] = '\0';
  225.     }
  226.     return buf;
  227.     }
  228.     return NULL;
  229.     
  230. }
  231.  
  232.  
  233. /*
  234.  *----------------------------------------------------------------------
  235.  *
  236.  * Utils_StringHashProc --
  237.  *
  238.  *    Default hashing function on strings.
  239.  *
  240.  * Results:
  241.  *    Integer key value.
  242.  *
  243.  * Side effects:
  244.  *    None.
  245.  *
  246.  * Note:
  247.  *      Default hashing function is to run over the string,
  248.  *      multiplying the current total by 9 and adding the new character.
  249.  *      Algorithm stolen directly from Ousterhout's tcl code.
  250.  *
  251.  *----------------------------------------------------------------------
  252.  */
  253.  
  254. int
  255. Utils_StringHashProc(key, keyLen, size)
  256.     Hash_Key key;             /* key to be hashed */
  257.     int keyLen;               /* size of key */
  258.     int size;                 /* size of table */
  259. {
  260.     unsigned char *keyString = (unsigned char *)key;
  261.     int val = 0;
  262.     register int letter;
  263.  
  264.     if ((size > 100000) || (size < 1)) {
  265.     sprintf(printBuf, "StringHashProc: Bad table size %d\n", size);    
  266.     }
  267.  
  268.     if (keyLen > 8) {
  269.     keyLen = 8;
  270.     }
  271.  
  272.     while (keyLen--) {
  273.     letter = *keyString++;
  274.     val = (val << 3) + letter;
  275.     }
  276.  
  277.     if (val < 0) {
  278.     sprintf(printBuf, "StringHashProc: Bad key %d\n", val);
  279.     Utils_Bailout(printBuf, BAIL_PRINT);
  280.     }
  281.     return (val % size);
  282. }
  283.  
  284.  
  285. /*
  286.  *----------------------------------------------------------------------
  287.  *
  288.  * Utils_IntegerHashProc --
  289.  *
  290.  *    Default hashing function on integers.
  291.  *
  292.  * Results:
  293.  *    Integer key value.
  294.  *
  295.  * Side effects:
  296.  *    None.
  297.  *
  298.  *----------------------------------------------------------------------
  299.  */
  300.  
  301. int
  302. Utils_IntegerHashProc(key, keyLen, size)
  303.     Hash_Key key;             /* key to be hashed */
  304.     int keyLen;               /* size of key */
  305.     int size;                 /* size of table */
  306. {
  307.     int *keyInt = (int *)key;
  308.  
  309.     if ((size > 100000) || (size < 1)) {
  310.     sprintf(printBuf, "IntegerHashProc: Bad table size %d\n", size);
  311.     }
  312.  
  313.     return ((*keyInt) % size);
  314. }
  315.  
  316.  
  317. /*
  318.  *----------------------------------------------------------------------
  319.  *
  320.  * Utils_CvtInteger --
  321.  *
  322.  *      Convert a string to an integer in a given range.
  323.  *
  324.  * Results:
  325.  *    Return Code.
  326.  *
  327.  * Side effects:
  328.  *    none.
  329.  *
  330.  * Note: 
  331.  *      string is interpreted as hex if it begins "0x"
  332.  *                               oct if it begins "0"
  333.  *                           and dec otherwise
  334.  *
  335.  *----------------------------------------------------------------------
  336.  */
  337.  
  338. int
  339. Utils_CvtInteger(string, low, high, valPtr)
  340.     char *string;             /* ascii number to convert */
  341.     int low;                  /* lowest acceptable value */
  342.     int high;                 /* highest acceptable value */
  343.     int *valPtr;              /* converted value */
  344. {
  345.     char *endPtr;
  346.  
  347.     *valPtr = strtol(string, &endPtr, 0);
  348.  
  349.     if ((*endPtr != '\0') || (*valPtr < low) || (*valPtr > high)) {
  350.     return T_FAILURE;
  351.     }
  352.  
  353.     return T_SUCCESS;
  354.     
  355. }
  356.  
  357.  
  358. /*
  359.  *----------------------------------------------------------------------
  360.  *
  361.  * Utils_GetLoginByUid --
  362.  *
  363.  *    Convert user id into login string name
  364.  *
  365.  * Results:
  366.  *      user name.
  367.  *
  368.  * Side effects:
  369.  *    Allocates string space.
  370.  *
  371.  *----------------------------------------------------------------------
  372.  */
  373.  
  374. char *
  375. Utils_GetLoginByUid(uid)
  376.     int uid;                  /* user id */
  377. {
  378.     struct passwd *entryPtr;
  379.     char dummy = '\0';
  380.     uid_t uidShort = (uid_t) uid;
  381.  
  382.     entryPtr = getpwuid(uidShort);
  383.  
  384.     if (entryPtr == (struct passwd *)NULL) {
  385.     return (Str_Dup(&dummy));
  386.     }
  387.  
  388.     return (Str_Dup(entryPtr->pw_name));
  389.  
  390. }
  391.  
  392.  
  393. /*
  394.  *----------------------------------------------------------------------
  395.  *
  396.  * Utils_GetGroupByGid --
  397.  *
  398.  *    Convert group id into group string name
  399.  *
  400.  * Results:
  401.  *      user name.
  402.  *
  403.  * Side effects:
  404.  *    Allocates string space.
  405.  *
  406.  *----------------------------------------------------------------------
  407.  */
  408.  
  409. char *
  410. Utils_GetGroupByGid(gid)
  411.     int gid;                  /* group id */
  412. {
  413.     struct group *entryPtr;
  414.     char dummy = '\0';
  415.     gid_t gidShort = (gid_t) gid;
  416.  
  417.     entryPtr = getgrgid(gidShort);
  418.  
  419.     if (entryPtr == (struct group *)NULL) {
  420.     return (Str_Dup(&dummy));
  421.     }
  422.  
  423.     return (Str_Dup(entryPtr->gr_name));
  424.  
  425. }
  426.  
  427.  
  428.  
  429. /*
  430.  *----------------------------------------------------------------------
  431.  *
  432.  * Utils_GetUidByLogin --
  433.  *
  434.  *    Convert a username string to a user id
  435.  *
  436.  * Results:
  437.  *    userid
  438.  *
  439.  * Side effects:
  440.  *    None.
  441.  *
  442.  *----------------------------------------------------------------------
  443.  */
  444.  
  445. int
  446. Utils_GetUidByLogin(login)
  447.     char *login;              /* login name */
  448. {
  449.     struct passwd *entryPtr;
  450.  
  451.     entryPtr = getpwnam(login);
  452.  
  453.     if (entryPtr == (struct passwd *)NULL) {
  454.     return T_FAILURE;
  455.     }
  456.  
  457.     return entryPtr->pw_uid;
  458.  
  459. }
  460.  
  461. /*
  462.  *----------------------------------------------------------------------
  463.  *
  464.  * Utils_GetGidByGroup --
  465.  *
  466.  *    Convert a group name string to a group id
  467.  *
  468.  * Results:
  469.  *    groupid
  470.  *
  471.  * Side effects:
  472.  *    None.
  473.  *
  474.  *----------------------------------------------------------------------
  475.  */
  476.  
  477. int
  478. Utils_GetGidByGroup(group)
  479.     char *group;              /* group name */
  480. {
  481.     struct group *entryPtr;
  482.  
  483.     entryPtr = getgrnam(group);
  484.  
  485.     if (entryPtr == (struct group *)NULL) {
  486.     return T_FAILURE;
  487.     }
  488.  
  489.     return entryPtr->gr_gid;
  490.  
  491. }
  492.  
  493.  
  494. /*
  495.  *----------------------------------------------------------------------
  496.  *
  497.  * Utils_MakeErrorMsg --
  498.  *
  499.  *    Interpret error code from server
  500.  *
  501.  * Results:
  502.  *    static (semi) descriptive character string.
  503.  *
  504.  * Side effects:
  505.  *    None.
  506.  *
  507.  *----------------------------------------------------------------------
  508.  */
  509.  
  510. char *
  511. Utils_MakeErrorMsg(status, syserr)
  512.     int status;               /* Jaquith error number. See jaquith.h */
  513.     int syserr;               /* errno */
  514. {
  515.     static char *msgList[] = {
  516.     "",
  517.     "Bad message version. Recompile application?\n",
  518.     "Bad message format. Application error?\n",
  519.     "Unknown command. Application error?\n",
  520.     "Permission denied.\n",
  521.     "I/O operation failed.\n",
  522.     "Indexing operation failed.\n",
  523.     "Buffering operation failed.\n",
  524.     "Meta-buffering operation failed.\n",
  525.     "Robot operation failed.\n",
  526.     "Volume unknown.\n",
  527.     "Exec failed.\n",
  528.     "No such archive. Use 'jstat -archlist' for an archive list.\n"
  529.     };
  530.  
  531.     if ((status < 0) || (status > T_MAXERR)) {
  532.     sprintf(printBuf, "MakeErrorMsg: unknown type. Status %d\n",
  533.         status);
  534.     } else {
  535.     strcpy(printBuf, msgList[status]);
  536.     }
  537.  
  538.     if (syserr != 0) {
  539.     if ((syserr < 0) || (syserr > sys_nerr)) {
  540.         sprintf(printBuf, "MakeErrorMsg: unknown type. Errno %d\n",        
  541.             syserr);
  542.     } else {
  543.         strcat(printBuf, sys_errlist[syserr]);
  544.         strcat(printBuf, "\n");
  545.     }
  546.  
  547.     }
  548.  
  549.     return printBuf;
  550. }
  551.  
  552.  
  553. /*
  554.  *----------------------------------------------------------------------
  555.  *
  556.  * Utils_SendMail --
  557.  *
  558.  *    Send mail routine
  559.  *
  560.  * Results:
  561.  *      none.
  562.  *
  563.  * Side effects:
  564.  *    Sends msg through mail system
  565.  *
  566.  *----------------------------------------------------------------------
  567.  */
  568.  
  569. int
  570. Utils_SendMail(recipient, msg, type)
  571.     char *recipient;          /* email name of recipient */
  572.     char *msg;                /* text of message */
  573.     char *type;               /* message severity */
  574. {
  575.     sprintf(printBuf,
  576.         "echo \"Automagic Jaquith %s:\n%s\n\" | mail -s \"Jaquith %s\" %s\n",
  577.         type, msg, type, recipient);
  578.     return (system(printBuf));
  579.  
  580. }
  581.  
  582.  
  583. /*
  584.  *----------------------------------------------------------------------
  585.  *
  586.  * Utils_FreeFileStat --
  587.  *
  588.  *    Release space for a T_FileStat
  589.  *
  590.  * Results:
  591.  *    None.
  592.  *
  593.  * Side effects:
  594.  *    Deallocates space.
  595.  *
  596.  *----------------------------------------------------------------------
  597.  */
  598.  
  599. void
  600. Utils_FreeFileStat(statInfoPtr, memFlag)
  601.     T_FileStat *statInfoPtr;  /* file info to be freed */
  602.     int memFlag;              /* release containing block, too */
  603. {
  604.  
  605.     MEM_FREE("FreeFile", statInfoPtr->fileName);
  606.     MEM_FREE("FreeFile", statInfoPtr->linkName);
  607.     MEM_FREE("FreeFile", statInfoPtr->uname);
  608.     MEM_FREE("FreeFile", statInfoPtr->gname);
  609.     MEM_FREE("FreeFile", statInfoPtr->abstract);
  610.     MEM_FREE("FreeFile", statInfoPtr->fileList);
  611.     if (memFlag) {
  612.     MEM_FREE("FreeFile", statInfoPtr);
  613.     }
  614.  
  615. }
  616.  
  617.  
  618. /*
  619.  *----------------------------------------------------------------------
  620.  *
  621.  * Utils_CopyFileStat --
  622.  *
  623.  *    Allocate space for a T_FileStat
  624.  *
  625.  * Results:
  626.  *    None.
  627.  *
  628.  * Side effects:
  629.  *    Calls MEM_ALLOC.
  630.  *
  631.  *----------------------------------------------------------------------
  632.  */
  633.  
  634. T_FileStat *
  635. Utils_CopyFileStat(statInfoPtr)
  636.     T_FileStat *statInfoPtr;  /* source file data */
  637. {
  638.     T_FileStat *newInfoPtr;
  639.  
  640.     newInfoPtr = (T_FileStat *)MEM_ALLOC("CopyFileStat", sizeof(T_FileStat));
  641.     *newInfoPtr = *statInfoPtr;
  642.     newInfoPtr->fileName = Str_Dup(statInfoPtr->fileName);
  643.     newInfoPtr->linkName = Str_Dup(statInfoPtr->linkName);
  644.     newInfoPtr->uname    = Str_Dup(statInfoPtr->uname);
  645.     newInfoPtr->gname    = Str_Dup(statInfoPtr->gname);
  646.     newInfoPtr->abstract = Str_Dup(statInfoPtr->abstract);
  647.     newInfoPtr->fileList = Str_Dup(statInfoPtr->fileList);
  648.  
  649.     return newInfoPtr;
  650. }
  651.  
  652.  
  653. /*
  654.  *----------------------------------------------------------------------
  655.  *
  656.  * Utils_GetOk --
  657.  *
  658.  *    Get confirmation from user.
  659.  *
  660.  * Results:
  661.  *    None.
  662.  *
  663.  * Side effects:
  664.  *    None.
  665.  *
  666.  *----------------------------------------------------------------------
  667.  */
  668.  
  669. int
  670. Utils_GetOk(msg)
  671.     char *msg;                /* Text message */
  672. {
  673.     char response[T_MAXLINELEN];
  674.     int ok = 0;
  675.     int notOk = 0; 
  676.  
  677.     while ((!ok) && (!notOk)) {
  678.     fputs(msg, stderr);
  679.     fflush(stderr);
  680.     gets(response);
  681.     if ((ok=Str_Match(response, "{y,Y,yes,Yes,YES}")) ||
  682.         (notOk=Str_Match(response, "{n,N,no,NO}"))) {
  683.         return ok;
  684.     }
  685.     }
  686.     return ok;    /* just to make compiler happy */
  687. }
  688.  
  689.  
  690. /*
  691.  *----------------------------------------------------------------------
  692.  *
  693.  * Utils_GetInteger -- 
  694.  *
  695.  *    Read an integer from user
  696.  *
  697.  * Results:
  698.  *    none.
  699.  *
  700.  * Side effects:
  701.  *    Program terminates of user enters nothing.
  702.  *
  703.  *----------------------------------------------------------------------
  704.  */
  705.  
  706. int
  707. Utils_GetInteger(msg, low, high)
  708.     char *msg;                /* Text message */
  709. {
  710.     int i;
  711.     char answer[T_MAXLINELEN];
  712.  
  713.     while (1) {
  714.     fprintf(stderr, msg);
  715.     gets(answer);
  716.     if (!*answer) {
  717.         exit(-1);
  718.     }
  719.     if (Utils_CvtInteger(answer, low, high, &i) == T_SUCCESS) {
  720.         return i;
  721.     }
  722.     }
  723. }
  724.  
  725.